home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / telecomm / sticpsrc.lzh / SOURCE.ARC / UNIX.C < prev    next >
Text File  |  1990-07-12  |  18KB  |  872 lines

  1. /* OS- and machine-dependent stuff for UNIX */
  2. /* collected from a lot of other stuff from different releases of the package */
  3. /* Written by Mikel Matthews, N9DVG */
  4. /* SYS5 stuff added by Jere Sandidge, K4FUM */
  5. /* cleanup and adaption into NETCHL by PE1CHL */
  6.  
  7. #include <stdio.h>
  8. #include <ctype.h>
  9. #include <errno.h>
  10. #include <fcntl.h>
  11. #include <termio.h>
  12. #include <sys/types.h>
  13. #include <sys/times.h>
  14. #include <sys/ndir.h>
  15. #include <sys/select.h>
  16. #include <sys/stat.h>
  17. #include <prototypes.h>
  18.  
  19. #include "global.h"
  20. #include "config.h"
  21. #include "mbuf.h"
  22. #include "internet.h"
  23. #include "iface.h"
  24. #include "cmdparse.h"
  25. #include "timer.h"
  26. #include "environ.h"
  27. #include "asy.h"
  28. #include "unix.h"
  29.  
  30. #ifndef B19200
  31. #define B19200    EXTA
  32. #endif
  33.  
  34. #ifndef B38400
  35. #define B38400    EXTB
  36. #endif
  37.  
  38. #if (defined(FD_SETSIZE) && !defined(M_I86MM))
  39. #define SELECT                /* we can use the select() call */
  40.  
  41. # ifdef FD_ZERO
  42. #  define bzero(s,n)    memset(s,0,n)    /* there is no bzero() in the lib! */
  43. #  define NUL_SET    {0}
  44. # else
  45. typedef unsigned long fd_set;        /* equivalents of FD_xxx macros */
  46. #  define FD_ZERO(fdsp)        *(fdsp) = 0
  47. #  define FD_SET(fd,fdsp)    *(fdsp) |= (1 << (fd))
  48. #  define FD_CLR(fd,fdsp)    *(fdsp) &= ~(1 << (fd))
  49. #  define FD_ISSET(fd,fdsp)    (*(fdsp) & (1 << (fd)))
  50. #  define NUL_SET    0
  51. # endif
  52. #endif
  53.  
  54. struct asy asy[ASY_MAX];
  55. struct interface *ifaces;
  56.  
  57. unsigned nasy = 0;            /* number of ASY interfaces */
  58.  
  59. #ifdef SERVERS
  60. extern FILE *logfp;            /* log file pointer */
  61. extern char logname[];            /* log file name */
  62. #endif
  63.  
  64. #ifdef TRACE
  65. extern FILE *trfp;            /* trace file pointer */
  66. extern char trname[];            /* trace file name */
  67. #endif
  68.  
  69. #ifdef IP
  70. extern struct mbuf *loopq;
  71. #endif
  72. #ifdef AX25
  73. extern struct mbuf *axloopq;
  74. #endif
  75.  
  76. static struct termio saved_termio;    /* termio on program startup */
  77. static struct termio our_termio;    /* termio during program run */
  78.  
  79. #ifdef SELECT
  80. static char *envselect;            /* options passed using SELECT envvar */
  81. static int noselect = 0;        /* # of fd's NOT supporting select */
  82. static int maxfd = 0;            /* # of fd's for select() */
  83. static fd_set port_set = NUL_SET;    /* set containing all serial devices */
  84. static fd_set read_set = NUL_SET;    /* returned set from last select() */
  85. static prg_busy = 0;            /* set when busy */
  86. #endif
  87.  
  88. static char ttbuf[BUFSIZ];        /* buffer used for stdout buffering */
  89.  
  90. /* Called at startup time to set up console I/O */
  91. ioinit()
  92. {
  93. #ifdef SELECT
  94.     fd_set fdset;            /* trial set for select */
  95.     struct timeval timeout;
  96. #endif
  97.  
  98.     setbuf(stdout,ttbuf);        /* buffering for stdout */
  99.  
  100.     tzset();            /* init the timezone variable */
  101.  
  102.     ioctl(0,TCGETA,&saved_termio);    /* read and save termio state */
  103.  
  104.     /* copy termio and drop input processing, echo, and INTR signal */
  105.     /* the VMIN/VTIME will be set up for immediate return when no key */
  106.  
  107.     ASSIGN(our_termio,saved_termio);
  108.     our_termio.c_lflag &= ~(ICANON|ECHO);
  109.     our_termio.c_cc[VINTR] = 0xff;
  110.     our_termio.c_cc[VMIN] = 0;
  111.     our_termio.c_cc[VTIME] = 0;
  112.  
  113. #ifdef SELECT
  114.     envselect = getnenv("SELECT");    /* get SELECT var settings */
  115.  
  116.     if (strchr(envselect,'k') != NULL)    /* select() on keyboard? */
  117.     {
  118.         /* check if stdin can use select() */
  119.  
  120.         FD_ZERO(&fdset);        /* setup an fd_set for stdin */
  121.         FD_SET(0,&fdset);
  122.         timeout.tv_sec = timeout.tv_usec = 0;
  123.  
  124.         if (select(1,&fdset,NULL,NULL,&timeout) < 0)
  125.         {
  126.             if (errno == EINVAL)    /* no select() support */
  127.                 printf("warning: stdin device does not support select()\n");
  128.             else
  129.                 perror("stdin select");
  130.  
  131.             noselect++;
  132.         }
  133.         else            /* select() went okay */
  134.         {
  135.             maxfd = 1;    /* select on fd #0 */
  136.             FD_SET(0,&port_set); /* enter stdin in the select set */
  137.             our_termio.c_cc[VMIN] = 1; /* can wait on read() */
  138.             our_termio.c_cc[VTIME] = 2;
  139.         }
  140.     }
  141.     else
  142.         noselect++;        /* no select on stdin */
  143. #endif
  144.  
  145.     ioctl(0,TCSETA,&our_termio);    /* set our termio values */
  146. }
  147.  
  148. /* Called just before exiting to restore console state */
  149. iostop()
  150. {
  151.     while(ifaces != NULLIF){
  152.         /* first flush the interface's buffers */
  153.         while(ifaces->recv != NULLVFP && (*ifaces->recv)(ifaces))
  154.             ;
  155.         if(ifaces->stop != NULLFP)
  156.             (*ifaces->stop)(ifaces);
  157.         ifaces = ifaces->next;
  158.     }
  159.  
  160.     ioctl(0,TCSETAW,&saved_termio); /* reset to original state */
  161. }
  162.  
  163. /* Spawn subshell */
  164. doshell(argc,argv)
  165. int argc;
  166. char *argv[];
  167. {
  168.     char *command,**envp;
  169.     int ret;
  170.  
  171. #ifdef SERVERS
  172.     if (logfp != NULLFILE)        /* logging to file? */
  173.         fclose(logfp);        /* close the logfile */
  174. #endif
  175.  
  176. #ifdef TRACE
  177.     if (trfp != stdout)        /* trace to file? */
  178.         fclose(trfp);        /* close it during shell exec */
  179. #endif
  180.  
  181.     fflush(stdout);
  182.  
  183.     ioctl(0,TCSETAW,&saved_termio);    /* set original terminal mode */
  184.  
  185.     if((command = getenv("SHELL")) == NULLCHAR)
  186.         command = "/bin/sh";    /* default command interpreter */
  187.  
  188.     envp = make_env();        /* create envinronment array */
  189.  
  190.     switch (fork())            /* spawn a subprocess */
  191.     {
  192.     case -1:            /* an error occurred... */
  193.         perror("fork");
  194.         ret = -1;
  195.         break;
  196.     case 0:                /* this is the child */
  197.         execve(command,argv,envp);
  198.         perror(command);
  199.         exit(1);
  200.     default:            /* this is the parent */
  201.         wait(&ret);        /* wait for child to terminate */
  202.         break;
  203.     }
  204.  
  205.     ioctl(0,TCSETAW,&our_termio);    /* our terminal mode again */
  206.  
  207.     free_env();            /* free the envp and temp env */
  208.  
  209. #ifdef SERVERS
  210.     if (logfp != NULLFILE)        /* re-open logfile if it was open */
  211.         logfp = fopen(logname,"a+");
  212. #endif
  213.  
  214. #ifdef TRACE
  215.     if (trfp != stdout)        /* re-open tracefile if not stdout */
  216.         if ((trfp = fopen(trname,"a+")) == NULLFILE)
  217.         trfp = stdout;
  218. #endif
  219.  
  220.     if (ret != 0)
  221.         return -1;
  222.  
  223.     return 0;
  224. }
  225.  
  226. /* checks the time then ticks and updates ISS */
  227. static time_t clkval = 0;
  228. void
  229. check_time()
  230. {
  231.     int32 iss();
  232.     time_t ntime;
  233.     int maxticks = SEC2TICK(15);    /* upper limit on delayed ticks */
  234.     struct tms tms;            /* dummy required by times() */
  235.  
  236.     if(clkval == 0){
  237.         /* Executed only once */
  238.         clkval = times(&tms);
  239.         return;
  240.     }
  241.  
  242.     ntime = times(&tms);        /* read elapsed time */
  243.  
  244.     while(ntime != clkval){        /* Handle possibility of several missed ticks */
  245. #ifdef IP
  246.         icmpclk();        /* Call this one before tick */
  247. #endif
  248.         tick();
  249. #ifdef IP
  250.         (void)iss();
  251. #endif
  252.         if(maxticks--)        /* check limit on ticks to handle */
  253.             clkval++;
  254.         else
  255.             clkval = ntime; /* ignore any remaining ticks */
  256.     }
  257. }
  258.  
  259. /* Read characters from the keyboard, translating them to internal codes.
  260.  * If none are ready, return -1
  261.  * This piece of code crudely assumes that you are on an ANSI terminal...
  262.  */
  263. int
  264. kbread()
  265. {
  266.     int c;
  267. #ifdef SELECT
  268.     struct timeval timeout;
  269.  
  270.     if (stdin->_cnt == 0 &&        /* no buffered characters? */
  271.             maxfd > 0)            /* select() allowed? */
  272.     {
  273.         read_set = port_set;
  274.         timeout.tv_sec = timeout.tv_usec = 0;
  275.  
  276. #ifdef IP
  277.         if (loopq == NULLBUF)    /* nothing on IP loopback? */
  278. #endif
  279. #ifdef AX25
  280.         if (axloopq == NULLBUF)    /* nothing on AX.25 loopb? */
  281. #endif
  282.  
  283.         if (noselect || prg_busy) /* reason to stay awake? */
  284.             timeout.tv_usec = 20000; /* short sleeptime */
  285.         else
  286.             timeout.tv_sec = 1; /* sleep for a long time */
  287.  
  288.         prg_busy = 1;        /* assume we are busy */
  289.  
  290.         if (select(maxfd,&read_set,NULL,NULL,&timeout) >= 0)
  291.         {
  292. #ifdef DEBUG
  293.             int i;
  294.  
  295.             printf("select:");
  296.             for (i = 0; i < maxfd; i++)
  297.                 if (FD_ISSET(i,&read_set))
  298.                     printf(" %d",i);
  299.             printf("\n");
  300.             fflush(stdout);
  301. #endif
  302.         }
  303.         else
  304.         {
  305. #ifdef DEBUG
  306.             perror("select:");
  307. #endif
  308.  
  309.             return -1;    /* error in select() */
  310.         }
  311.  
  312.         if (FD_ISSET(0,&port_set) && !FD_ISSET(0,&read_set))
  313.             return -1;    /* select() says no input available */
  314.     }
  315. #endif
  316.  
  317.     if((c = getchar()) == EOF)
  318.         return -1;        /* no input available */
  319.  
  320.     if(c == 0x1b){            /* ESC character? */
  321.         /* Lead-in to a special char */
  322.         if(getchar() != '[')
  323.             return 0x1b;
  324.  
  325.         switch(c = getchar())
  326.         {
  327.         case 'M':        /* F-1 key */
  328.             c = -11;
  329.             break;
  330.         case 'N':        /* F-2 key */
  331.             c = -10;
  332.             break;
  333.         case 'O':        /* F-3 key */
  334.             c = -9;
  335.             break;
  336.         case 'P':        /* F-4 key */
  337.             c = -8;
  338.             break;
  339.         case 'Q':        /* F-5 key */
  340.             c = -7;
  341.             break;
  342.         case 'R':        /* F-6